package com.xhwl.data.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xhwl.common.dto.cent.sdata.OrgNodeDTO;
import com.xhwl.common.dto.cent.sdata.OrganizationDTO;
import com.xhwl.common.enums.BusinessRangeTypeEnum;
import com.xhwl.common.enums.OrganizationTypeEnum;
import com.xhwl.common.enums.space.ViewType;
import com.xhwl.common.pojo.ResultJson;
import com.xhwl.common.pojo.cent.sdata.*;
import com.xhwl.common.pojo.cent.sdata.personnel.StaffOrganization;
import com.xhwl.common.pojo.config.OrganizationConfig;
import com.xhwl.common.query.OrganizationConfigQuery;
import com.xhwl.common.query.cent.sdata.*;
import com.xhwl.common.utils.IpUtil;
import com.xhwl.common.utils.PageUtil;
import com.xhwl.common.utils.StringUtils;
import com.xhwl.common.utils.ThreadLocalUtil;
import com.xhwl.data.pojo.dto.OrganizationConfigDTO;
import com.xhwl.data.pojo.dto.personal.OrgStaffListQueryDTO;
import com.xhwl.data.pojo.dto.personal.OrgStaffTreeDTO;
import com.xhwl.data.pojo.dto.personal.OrgStaffTreeQueryDTO;
import com.xhwl.data.pojo.vo.NameCheckedVO;
import com.xhwl.data.service.*;
import com.xhwl.data.service.personal.IStaffOrganizationService;
import com.xhwl.data.util.CodeGenerator;
import lombok.Data;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @Author: luyi
 * @Description:
 * @Date: Create in 14:19 2021/3/4
 */
@RestController
public class OrganizationController {

    @Autowired
    private IOrganizationService organizationService;

    @Autowired
    private IRoleService roleService;

    @Autowired
    private IOrganizationConfigFeignService organizationConfigFeignService;

    @Autowired
    private IOrganizationConfigService organizationConfigService;

    @Autowired
    private IOrganizationTypeService organizationTypeService;

    @Autowired
    private IStaffOrganizationService staffOrganizationService;

    @Autowired
    private IAccountProjectService accountProjectService;

    @Autowired
    private IProjectService projectService;

    @Autowired
    private IOrganizationManagerService organizationManagerService;
    @Autowired
    private IOrganizationImportService organizationImportService;
    @Autowired
    private ISpaceService spaceService;
    @Autowired
    private IAreaService areaService;
    @Autowired
    private IRoomService roomService;
    @Autowired
    private IFloorService floorService;
    @Autowired
    private IBlockService blockService;
    @Autowired
    private IBuildingService buildingService;
    @Autowired
    private IPublicAreaService publicAreaService;


    /**
     * default 类型创建默认限制10级，排除最顶级最顶层的企业
     */
    private static final int maxLevel = 11;
    //注册游客账号
    private String REGISTER_TOURIST_ROLE_CODE = "TOURIST1";

    private static final Logger log = LoggerFactory.getLogger(OrganizationController.class);

    /**
     * 判断当前操作人是否能选择
     *
     * @param account
     * @param organizationId
     * @return
     */
    @RequestMapping(value = "/org/can-select")
    public ResultJson canSelect(Account account, @RequestParam("organizationId") Integer organizationId) {
        Boolean result = organizationService.canSelect(account, organizationId);
        return ResultJson.success(result);
    }

    /**
     * 展示当前帐号相关的
     *
     * @param query
     * @param account
     * @return
     */
    @RequestMapping(value = "/org/tree")
    public ResultJson tree(@RequestBody OrganizationQuery query, Account account) {
        query.withAccountId(account.getId());
        if (!query.getIsAccountAuth() && query.getProjectIds().isEmpty()){
            return ResultJson.success(Collections.emptyList());
        }
        List<OrganizationDTO> tree = organizationService.treeWithManager(query);
        return ResultJson.success(tree);
    }

    /**
     * 查询新增/编辑企业返回关联空间类型
     * @param industryId
     * @param projectId
     * @return
     */
    @RequestMapping(value = "/org/enterprise-space/type",method = RequestMethod.POST)
    public ResultJson typeTree(@RequestHeader Short industryId,@RequestParam Integer projectId) {
        OrganizationConfigQuery organizationConfigQuery = new OrganizationConfigQuery();
        if (null != projectId) {
            organizationConfigQuery.withProjectId(projectId);
        }
        organizationConfigQuery.setIndustryId(industryId.intValue());
        List<OrganizationConfig> list = organizationConfigFeignService.list(organizationConfigQuery);
        if (list.isEmpty()) {
            log.error("获取组织配置信息失败，industryId = {} projectId = {}", industryId, projectId);
            return ResultJson.success();
        }
        Set<Integer> typeSet = new HashSet<>();
        List<Integer> types = null;
        if (null != projectId) {
            types = list.stream().filter(l -> null != l.getProjectId() && l.getProjectId().intValue() == projectId).map(l->l.getType()).collect(Collectors.toList());
        }
        typeSet.addAll(types);
        return ResultJson.success(typeSet);
    }

    /**
     *新增/编辑员工返回关联空间类型
     * @param industryId
     * @param projectIds
     * @return
     */
    @RequestMapping(value = "/org/enterprise-space/types",method = RequestMethod.POST)
    public ResultJson typesTree(@RequestHeader Short industryId,@RequestBody List<Integer> projectIds) {
        if (null != projectIds){
            Set<Integer> typeSet = new HashSet<>();
            typeSet.add(2);
            for (Integer projectId : projectIds) {
                OrganizationConfigQuery organizationConfigQuery = new OrganizationConfigQuery();
                if (null != projectId) {
                    organizationConfigQuery.withProjectId(projectId);
                }
                organizationConfigQuery.setIndustryId(industryId.intValue());
                List<OrganizationConfig> list = organizationConfigFeignService.list(organizationConfigQuery);
                if (list.isEmpty()) {
                    log.error("获取组织配置信息失败，industryId = {} projectId = {}", industryId, projectId);
                    continue;
                }
                List<Integer> types = null;
                if (null != projectId) {
                    types = list.stream().filter(l -> null != l.getProjectId() && l.getProjectId().intValue() == projectId).map(l->l.getType()).collect(Collectors.toList());
                }
                typeSet.addAll(types);
            }
            return ResultJson.success(typeSet);
        }
        return ResultJson.success();
    }

    /**
     * 不关联帐号权限的 通讯录用
     *
     * @param query
     * @return
     */
    @RequestMapping(value = "/org/tree-nop")
    public ResultJson treeNoP(@RequestBody OrganizationQuery query, Account account) {
        query.withIndustryId(account.getIndustryId());
        query.setVisibleAccount(account.getId());
        List<OrganizationDTO> tree = organizationService.treeWithManager(query);
        return ResultJson.success(tree);
    }

    /**
     * 根据房间状态获取树
     * @param query
     * @return
     */
    @RequestMapping(value = "/org/treeCp")
    public ResultJson treeCp(@RequestBody OrganizationQuery query) {
        List<OrganizationDTO> tree = organizationService.treeCp(query);
        return ResultJson.success(tree);
    }


    /**
     * 企业通讯录列表查询
     *
     * @return
     */
    @RequestMapping(value = "/org/contact-list")
    public ResultJson contactList(@RequestBody OrganizationQuery query, Account account) {
        query.withIndustryId(account.getIndustryId());
        query.setVisibleAccount(account.getId());
        return ResultJson.success(organizationService.contactList(query));
    }

    @RequestMapping(value = "/org/list")
    public ResultJson list(@RequestBody OrganizationQuery query, Account account, @RequestHeader Integer industryId) {
        query.withIndustryId(industryId.shortValue());
        List<OrganizationDTO> list = organizationService.listV2(query);
        return ResultJson.success(list);
    }

    /**
     * 根据楼层id，查询房间与床位的详情信息
     */
    @RequestMapping(value = "/org/room-space-list")
    public ResultJson roomSpaceList(@RequestBody OrganizationQuery query, Account account, @RequestHeader Integer industryId) {
        query.withIndustryId(industryId.shortValue());
        //先查询出该楼层下的所有房间信息
        List<OrganizationDTO> list = organizationService.listV2(query);
        //封装房间扩展字段信息
        for (OrganizationDTO organizationDTO : list) {
            QueryWrapper<Room> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("organization_id",organizationDTO.getId());
            Room room = roomService.getOne(queryWrapper);
            if (null != room){
                organizationDTO.setExpand(room.getExpand());
            }else {
                log.info("房间`{}`为空，请确认该房间是否存在",room.getId());
                continue;
            }
            //查询该房间下的床位信息
            OrganizationQuery organizationQuery = new OrganizationQuery();
            organizationQuery.setTypes(query.getTypes());
            organizationQuery.setProjectId(query.getProjectId());
            organizationQuery.setIndustryId(industryId.shortValue());
            organizationQuery.setParentId(room.getOrganizationId());
            List<OrganizationDTO> spaces = organizationService.listV2(organizationQuery);
            //封装床位扩展字段信息
            for (OrganizationDTO space : spaces) {
                QueryWrapper<Space> spaceQueryWrapper = new QueryWrapper<>();
                spaceQueryWrapper.eq("org_id",space.getId());
                Space spaceData = spaceService.getOne(spaceQueryWrapper);
                if (null != spaceData){
                    space.setSpaceData(spaceData.getData());
                }
            }
            //将床位信息封装到该房间中
            organizationDTO.setSpaceBeds(spaces);
        }
        return ResultJson.success(list);
    }

    /**
     * 项目选择器，返回树结构 企业-组织-项目
     *
     * @param query
     * @param account
     * @return
     */
    @RequestMapping(value = "/org/project-chose")
    public ResultJson projectChose(@RequestBody OrganizationQuery query, Account account) {
        query.withAccountId(account.getId());
        List<OrganizationDTO> result = null;
        if (roleService.isSuperManager(account.getId()) || roleService.isEntManager(account.getId())) {
            result = organizationService.adminProjectChose(query);
        } else {
            result = organizationService.projectChose(query);
        }
        return ResultJson.success(result);
    }

    /**
     * 只展示企业和企业下的项目，不展示组织等其他结构
     *
     * @param query
     * @param account
     * @return
     */
    @RequestMapping(value = "/org/project-chose/v2")
    public ResultJson projectChoseV2(@RequestBody OrganizationQuery query, @RequestHeader Short industryId, Account account) {
        query.withAccountId(account.getId());
        query.withIndustryId(industryId);
        List<OrganizationDTO> result = organizationService.projectChoseV2(query);
        return ResultJson.success(result);
    }

    /**
     * 项目选择器 没有层级结构 前台用 只有企管和普通角色
     * @param account
     * @return
     */
    @PostMapping(value = "/org/project-chose/v3")
    public ResultJson projectChoseV3(@RequestBody OrganizationQuery organizationQuery,  Account account){
        if(null == account || null == account.getId()){
            return ResultJson.fail("不存在帐号信息");
        }
        if (!organizationQuery.getIsAccountAuth() && null != organizationQuery.getRoleIds() && organizationQuery.getRoleIds().isEmpty()){
            return ResultJson.success(Collections.emptyList());
        }
        organizationQuery.setAccountId(account.getId());
        return ResultJson.success(organizationService.projectChoseV3(organizationQuery,account));
    }
    /**
     * 项目选择器 分页
     * @param account
     * @return
     */
    @PostMapping(value = "/org/project-chose-page")
    public ResultJson projectChosePage(@RequestBody OrganizationQuery organizationQuery,Page page,  Account account){
        if(null == account || null == account.getId()){
            return ResultJson.fail("不存在帐号信息");
        }
        if (!organizationQuery.getIsAccountAuth() && null != organizationQuery.getRoleIds() && organizationQuery.getRoleIds().isEmpty()){
            return ResultJson.success(Collections.emptyList());
        }
        organizationQuery.setAccountId(account.getId());
        List<Project> projects = organizationService.projectChoseV3(organizationQuery,account);
        page.setRecords(PageUtil.page(page,projects));
        return ResultJson.success(page);
    }


    @RequestMapping(value = "/org/name-check")
    public ResultJson nameCheck(@RequestBody NameCheckedVO nameChecked) {
        OrganizationQuery organizationQuery = new OrganizationQuery();
        if (null == nameChecked || StringUtils.isEmpty(nameChecked.getName())) {
            return ResultJson.fail("检查不通过");
        }
        if (2 > nameChecked.getName().trim().length() || 50 < nameChecked.getName().trim().length()) {
            return ResultJson.fail("长度超过限制");
        }
        if (null == nameChecked.getParentId()) {
            return ResultJson.fail("参数错误");
        }
        if (null != nameChecked.getOrgId()) {
            organizationQuery.withExcludeId(nameChecked.getOrgId());
        }
        organizationQuery.withName(nameChecked.getName());
        organizationQuery.withParentId(nameChecked.getParentId());
        List<Organization> list = organizationService.list(organizationQuery);
        if (list.size() > 0) {
            return ResultJson.fail("名称重复");
        }
        return ResultJson.success("名称可用");
    }

    /**
     * 校验组织编码唯一性
     */
    @GetMapping("/org/code-unique-check")
    public ResultJson codeCheck(@RequestParam("parentId") Integer parentId,@RequestParam("code") String code,@RequestParam(value = "id",required = false)Integer id){
        if (StringUtils.isEmpty(code)){
            return ResultJson.fail("检查不通过");
        }

        String pattern = "^[A-Za-z0-9]{6,10}$";
        if (!code.matches(pattern)){
            return ResultJson.fail("不满足6-10位数字/字母组合");
        }
        if (null ==parentId){
            return ResultJson.fail("参数错误");
        }
        Organization parentOrg = organizationService.getById(parentId);
        //上级组织不存在
        if (null == parentOrg){
            return ResultJson.fail("上级组织id错误");
        }
        QueryWrapper<Organization> organizationQueryWrapper = new QueryWrapper<>();
        organizationQueryWrapper
                .eq("code",code)
                .eq("is_deleted",0)
                .eq("enterprise_id",parentOrg.getEnterpriseId());
        if (null != id){
            //编辑验重排除它自己
            organizationQueryWrapper.ne("id",id);
        }
        List<Organization> organizations = organizationService.list(organizationQueryWrapper);
        if (organizations.size() > 0){
            return ResultJson.fail("编码重复");
        }
        return ResultJson.success("编码可用");
    }

    /**
     * 组织配置树（项目没有配置的时候不展示）
     *
     * @param industryId
     * @param projectId
     * @return
     */
    @RequestMapping(value = "/org/config")
    public ResultJson organizationConfig(@RequestHeader Short industryId, Integer projectId) {
        OrganizationConfigQuery organizationConfigQuery = new OrganizationConfigQuery();
        if (null != projectId) {
            organizationConfigQuery.withProjectId(projectId);
        }
        organizationConfigQuery.setIndustryId(industryId.intValue());
        List<OrganizationConfig> list = organizationConfigFeignService.list(organizationConfigQuery);
        if (list.isEmpty()) {
            log.error("获取组织配置信息失败，industryId = {} projectId = {}", industryId, projectId);
            return ResultJson.success();
        }
        if (null != projectId) {
            list = list.stream().filter(l -> null != l.getProjectId() && l.getProjectId().intValue() == projectId).collect(Collectors.toList());
        }
        return ResultJson.success(tree(list));
    }

    /**
     * 组织配置树（项目没有配置的时候展示业态的）
     *
     * @param industryId
     * @param projectId
     * @return
     */
    @RequestMapping(value = "/org/config/show-default")
    public ResultJson organizationConfigShowDefault(@RequestHeader Short industryId, Integer projectId) {
        OrganizationConfigQuery organizationConfigQuery = new OrganizationConfigQuery();
        if (null != projectId) {
            organizationConfigQuery.withProjectId(projectId);
        }
        organizationConfigQuery.setIndustryId(industryId.intValue());
        List<OrganizationConfig> list = organizationConfigFeignService.list(organizationConfigQuery);
        if (null != projectId) {
            List<OrganizationConfig> projectConfig = list.stream().filter(l -> null != l.getProjectId() && l.getProjectId().intValue() == projectId).collect(Collectors.toList());
            if (!projectConfig.isEmpty()) {
                return ResultJson.success(tree(projectConfig));
            }
        }
        return ResultJson.success(tree(list));
    }

    /**
     * 查询下级配置组织结点
     *
     * @param industryId
     * @param projectId
     * @param type
     * @return
     */
    @RequestMapping(value = "/org/config/v2")
    public ResultJson organizationConfigV2(@RequestHeader Integer industryId, Integer projectId, @RequestParam("type") Integer type) {
        OrganizationConfigQuery organizationConfigQuery = new OrganizationConfigQuery();
        if (null != projectId) {
            organizationConfigQuery.withProjectId(projectId);
        } else {
            // 不传项目id的时候获取默认配置的规则
            organizationConfigQuery.withRange(Arrays.asList(BusinessRangeTypeEnum.DEFAULT));
        }
        organizationConfigQuery.setIndustryId(industryId);
        // 根据项目查询，没有就返回企业的配置，再没有返回业态的配置
        List<OrganizationConfig> next = organizationConfigService.next(organizationConfigQuery, type);
        return ResultJson.success(next);
    }

    /**
     * 新增 创建
     *
     * @param account
     * @param industryId
     * @param organizationConfigs
     * @return
     */
    @RequestMapping(value = "/org/config/create")
    public ResultJson organizationConfigCreate(Account account, @RequestHeader Integer industryId, @RequestBody List<OrganizationConfig> organizationConfigs) {
        if (organizationConfigs.isEmpty()) {
            return ResultJson.fail("参数为空");
        }
        for (OrganizationConfig organizationConfig : organizationConfigs) {
            if (null == organizationConfig.getProjectId()) {
                log.error("参数错误，{} 缺少projectId", organizationConfig.getName());
                return ResultJson.fail("参数错误");
            }
            if (null == organizationConfig.getLevel()) {
                log.error("参数错误, {} level 为空");
                return ResultJson.fail("参数错误");
            }
            organizationConfig.setIndustryId(industryId);
            organizationConfig.setRangeType(BusinessRangeTypeEnum.PROJECT);
        }
        log.info("创建组织配置入参 {}", JSONObject.toJSONString(organizationConfigs));
        return organizationConfigFeignService.batchCreate(organizationConfigs);
    }

    @RequestMapping(value = "/org/config/delete")
    public ResultJson configDelete(Integer id, Integer projectId, HttpServletRequest request) {
        if (null == id || null == projectId) {
            return ResultJson.fail("参数错误");
        }
        ThreadLocalUtil.setIp(IpUtil.getIpAddr(request));
        OrganizationConfigQuery organizationConfigQuery = new OrganizationConfigQuery();
        organizationConfigQuery.withId(id);
        OrganizationConfig one = organizationConfigFeignService.one(organizationConfigQuery);
        if (null == one) {
            return ResultJson.fail("配置不存在");
        }
        OrganizationQuery organizationQuery = new OrganizationQuery();
        organizationQuery.withTypes(Arrays.asList(one.getType()));
        organizationQuery.withProjectIds(Arrays.asList(projectId));
        List<Organization> list = organizationService.list(organizationQuery);
        if (list.isEmpty()) {
            return organizationConfigFeignService.delete(id);
        }
        return deleteOrganizationConfigHandler(one, projectId, list, id);
    }


    /**
     * story 707480522
     * 线上问题：
     *     结构类型下已录入数据，该结构类型不可删除，如“公区”下录入了数据，则不可删除“公区”类型。
     *     但是若区域下有公区、楼栋下也有公区，房间下也有公区时。即使只是在“房间-公区”下录入了数据，会导致区域下的公区、楼栋下的公区结构类型也无法删除。(其它结构等同)
     *     
     *     希望做到：能够根据该类型所在的具体层级节点，判断已录入数据不可删除。不影响其它节点删除。
     * @param one
     * @param projectId
     * @param list
     * @param id
     * @return
     */
    private ResultJson deleteOrganizationConfigHandler(OrganizationConfig one, Integer projectId, List<Organization> list, Integer id){
        OrganizationConfigQuery organizationConfigQuery1 = new OrganizationConfigQuery();
        organizationConfigQuery1.setProjectId(one.getProjectId());
        List<OrganizationConfig> list1 = organizationConfigFeignService.list(organizationConfigQuery1);
        if(list1.isEmpty()){
            ResultJson.fail("数据错误");
        }
        // 获取配置的上级所有结构
        List<Integer> spaceIds = organizationTypeService.spaceIds();
        list1  = list1.stream().filter(i -> spaceIds.contains(i.getType())).collect(Collectors.toList());
        // 要删除的空间配置所在树所有类型
        List<Integer> currentTypeList = new LinkedList<>();
        StringBuilder typeTreeString = new StringBuilder();
        OrganizationConfig curr = one;
        currentTypeList.add(curr.getType());
        typeTreeString.append(curr.getType());
        while(true){
            OrganizationConfig filter = curr;
            List<OrganizationConfig> collect = list1.stream().filter(i -> i.getId().equals(filter.getParentId())).collect(Collectors.toList());
            if(!collect.isEmpty()){
                curr = collect.get(0);
                currentTypeList.add(curr.getType());
                typeTreeString.append(curr.getType());
            }else{
                break;
            }
        }
        OrganizationQuery organizationQuery1 = new OrganizationQuery();
        organizationQuery1.setTypes(spaceIds.stream().distinct().collect(Collectors.toList()));
        organizationQuery1.withProjectIds(Arrays.asList(projectId));
        List<Organization> list2 = organizationService.list(organizationQuery1);
        // 转换成类型栈
        for (Organization organization : list) {
            Integer curr1 = organization.getParentId();
            StringBuilder sbd1 = new StringBuilder();
            sbd1.append(organization.getType());
            while (true){
                Integer filter = curr1;
                List<Organization> collect = list2.stream().filter(i -> i.getId().equals(filter)).collect(Collectors.toList());
                if(!collect.isEmpty()){
                    curr1 = collect.get(0).getParentId();
                    sbd1.append(collect.get(0).getType());
                }else{
                    break;
                }
            }
            if(sbd1.toString().equals(typeTreeString.toString())){
                return ResultJson.fail("已录入数据，不可删除");
            }
        }
        return organizationConfigFeignService.delete(id);
    }

    /**
     * 组织详情
     *
     * @param id
     * @return
     */
    @RequestMapping(value = "/org/detail")
    public ResultJson defaultOrganizationDetail(Integer id) {
        if (null == id) {
            return ResultJson.fail("参数错误");
        }
        OrganizationDTO detail = organizationService.detail(id);
        detail.setOrganizationId(detail.getId());
        return ResultJson.success(detail);
    }

    /**
     * 组织接口 新增 创建
     *
     * @param organizations
     * @param account
     * @param request
     * @return
     */
    @RequestMapping(value = "/org/default/create")
    public ResultJson defaultOrganizationBatchCreate(@RequestBody List<Organization> organizations, Account account, HttpServletRequest request) {
        if (organizations.isEmpty()) {
            return ResultJson.fail("参数错误");
        }
        ThreadLocalUtil.setIp(IpUtil.getIpAddr(request));
        for (Organization organization : organizations) {
            if (11 < organization.getLevel()) {
                return ResultJson.fail("超过层级上限");
            }
            organization.setType(4);
        }
        return organizationService.create(organizations);
    }

    /**
     * 修改组织
     *
     * @param organization
     * @return
     */
    @RequestMapping(value = "/org/default/edit")
    public ResultJson defaultOrganizationEdit(@RequestBody OrganizationDTO organization) {
        if (null == organization.getId()) {
            return ResultJson.fail("参数错误");
        }
        if (StringUtils.isEmpty(organization.getName())) {
            return ResultJson.fail("参数错误，名称为空");
        }
        if (null == organization.getParentId()) {
            return ResultJson.fail("参数错误，缺少上级");
        }
        // 设置类型为组织
        organization.setType(4);
        return organizationService.update2(organization);
    }

    @RequestMapping(value = "/org/delete")
    public ResultJson delete(Integer id) {
        return organizationService.delete(id, null);
    }

    /**
     * 根据业态获取组织类型（+项目）
     * 以前用来查询空间类型
     *
     * @param industryId
     * @return
     * @deprecated 可用/org/type/list 代替
     */
    @Deprecated
    @RequestMapping(value = "/org/type")
    public ResultJson type(@RequestHeader Short industryId) {
        OrganizationTypeQuery organizationTypeQuery = new OrganizationTypeQuery();
        organizationTypeQuery.withIndustryId(industryId);
        organizationTypeQuery.withViewType(ViewType.SPACE, ViewType.SPACE_DEFINED);
        List<OrganizationType> list = organizationTypeService.list(organizationTypeQuery);

        Map<String, String> result = new HashMap<>();
        if (CollectionUtils.isNotEmpty(list)) {
            for (OrganizationType organizationType : list) {
                result.put(organizationType.getCode(), organizationType.getName());
            }
        }
        return ResultJson.success(result);
    }

    /**
     * 获取指定类型空间数据（与账号无关）
     * @param orgNodeDTO
     * @return
     */
    @PostMapping(value = "/org/node/list")
    public ResultJson nodeList(@RequestBody OrgNodeDTO orgNodeDTO) {
        return ResultJson.success(organizationService.nodeListByType(orgNodeDTO));
    }

    /**
     * @param organizationType
     * @return
     * @deprecated 被 /org/config/v2 代替了
     */
    @Deprecated
    @RequestMapping(value = "/org/next")
    public ResultJson next(@RequestParam(value = "type", required = true) OrganizationTypeEnum organizationType) {
        List<OrganizationTypeEnum> next = organizationType.next;
        if (null != next) {
            return ResultJson.success(next.stream().collect(Collectors.toMap(Function.identity(), OrganizationTypeEnum::getDescription)));
        }
        return ResultJson.success(next);
    }

    /**
     * 根据组织id链式拼接完整名称
     *
     * @param organizationQuery 查询条件
     * @return 路址名称
     */
    @RequestMapping(value = "/org/full-name", method = RequestMethod.POST)
    public ResultJson fullName(@RequestBody OrganizationQuery organizationQuery) {
        return ResultJson.success().setResult(organizationService.fullName(organizationQuery));
    }
    /**
     * 根据组织id列表链式拼接完整名称
     *
     * @param organizationQuery 查询条件
     * @return 路址名称与ID的map
     */
    @RequestMapping(value = "/org/full-name-list", method = RequestMethod.POST)
    public ResultJson batchFullName(@RequestBody OrganizationQuery organizationQuery) {
        Map<Integer, String> nameMap = organizationService.batchFullName(organizationQuery);
        List<Organization> orgList = new ArrayList<>();
        nameMap.forEach((id,name)->{
            Organization organization = new Organization();
            organization.setId(id);
            organization.setName(name);
            orgList.add(organization);
        });
        return ResultJson.success(orgList);
    }

    /**
     * 获取项目下 房间链式拼接名称
     * @param organizationQuery
     * @return
     */
    @RequestMapping(value = "/org/full-name-list-v2", method = RequestMethod.POST)
    public ResultJson batchFullNameV2(@RequestBody OrganizationQuery organizationQuery) {
//        List<Organization> organizationList = organizationService.list(organizationQuery);

        List<Organization> organizationList = organizationService.child(organizationQuery);
        //过滤出房间类型
        organizationList = organizationList.stream().filter(i -> i.getType().equals(6)).collect(Collectors.toList());

        organizationQuery.setTypes(organizationTypeService.spaceIds());
        organizationQuery.setIds(organizationList.stream().map(Organization::getId).collect(Collectors.toList()));

        Map<Integer, String> nameMap = organizationService.batchFullName(organizationQuery);
        if (null == nameMap || nameMap.isEmpty()){
            return ResultJson.success();
        }
        List<Organization> orgList = new ArrayList<>();
        nameMap.forEach((id,name)->{
            Organization organization = new Organization();
            organization.setId(id);
            organization.setName(name);
            orgList.add(organization);
        });
        return ResultJson.success(orgList);
    }

    /**
     * 企业通讯录，编辑组织选择指定人可见时用到的树 异步生成树
     *
     * @return
     */
    @RequestMapping(value = "/org/staff/edit-tree")
    public ResultJson editTree(@RequestHeader Short clientType, @RequestBody OrgStaffListQueryDTO orgStaffListQueryDTO, Account account) {
        if (null == orgStaffListQueryDTO.getEnterpriseId()) {
            return ResultJson.fail("缺少企业信息");
        }
        Integer pId = 0;
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(orgStaffListQueryDTO.getParentId())) {
            try {
                String[] s1 = orgStaffListQueryDTO.getParentId().split("_");
                String s = s1[1];
                if (!s1[0].equals("o")) {
                    return ResultJson.success(Collections.emptyList());
                }
                pId = Integer.valueOf(s);
            } catch (Exception e) {
                e.printStackTrace();
                return ResultJson.success(Collections.emptyList());
            }
        }
        OrgStaffTreeQueryDTO orgStaffTreeQueryDTO = new OrgStaffTreeQueryDTO();
        orgStaffParamHandler(orgStaffTreeQueryDTO, pId, orgStaffListQueryDTO.getEnterpriseId(), orgStaffListQueryDTO.getKeywords());
        if (orgStaffListQueryDTO.getExcludeEntManager()){
            orgStaffTreeQueryDTO.setExcludeEntManager(true);
        }
        if (orgStaffListQueryDTO.getIsQueryUp()){
            orgStaffTreeQueryDTO.setIsQueryUp(true);
        }
        List<OrgStaffTreeDTO> result = null;
        if (clientType != null && 3 == clientType) {
            // pc端不需要过滤可见性权限
            result = organizationService.editTreeNoVisiable(orgStaffTreeQueryDTO);
        } else {
            orgStaffTreeQueryDTO.setAccountId(account.getId());
            result = organizationService.editTree(orgStaffTreeQueryDTO);
        }
        return ResultJson.success(result);
    }

    private void orgStaffParamHandler(OrgStaffTreeQueryDTO orgStaffTreeQueryDTO, Integer pId, Integer enterpriseId, String keywords) {
        if (0 != pId) {
            orgStaffTreeQueryDTO.setParentId(pId);
        }
        orgStaffTreeQueryDTO.setEnterpriseId(enterpriseId);
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(keywords)) {
            orgStaffTreeQueryDTO.setKeywords(keywords);
        }
    }

    /**
     * app企业通讯录 组织架构列表
     *
     * @param orgStaffListQueryDTO
     * @return
     */
    @RequestMapping(value = "/org/staff/org-staff-list")
    public ResultJson orgStaffList(@RequestBody OrgStaffListQueryDTO orgStaffListQueryDTO, Account account) {
        if (null == orgStaffListQueryDTO.getEnterpriseId()) {
            return ResultJson.fail("缺少企业信息");
        }
        String parentId = orgStaffListQueryDTO.getParentId();
        Integer pId = 0;
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(parentId)) {
            try {
                String[] s1 = parentId.split("_");
                String s = s1[1];
                if (!s1[0].equals("o")) {
                    return ResultJson.success(Collections.emptyList());
                }
                pId = Integer.valueOf(s);
            } catch (Exception e) {
                e.printStackTrace();
                return ResultJson.success(Collections.emptyList());
            }
        }
        Organization organization = organizationService.getById(pId);
        OrgStaffTreeQueryDTO orgStaffTreeQueryDTO = new OrgStaffTreeQueryDTO();
        orgStaffParamHandler(orgStaffTreeQueryDTO, pId, orgStaffListQueryDTO.getEnterpriseId(), orgStaffListQueryDTO.getKeywords());
        orgStaffTreeQueryDTO.setAccountId(account.getId());
        List<OrgStaffTreeDTO> result = organizationService.editTree(orgStaffTreeQueryDTO);
        setOrgNames(result,organization);
        return ResultJson.success(result);
    }

    private void setOrgNames(List<OrgStaffTreeDTO> orgStaffTreeDTOS,Organization organization) {
        if (CollectionUtils.isNotEmpty(orgStaffTreeDTOS)) {
            List<OrgStaffTreeDTO> accounts = orgStaffTreeDTOS.stream().filter(i -> i.getType().intValue() == 1).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(accounts)) {

                List<Integer> accountIds = accounts.stream().map(i -> i.getRelationId()).collect(Collectors.toList());
                // 查询账号所属的组织
                QueryWrapper<StaffOrganization> staffOrganizationQueryWrapper = new QueryWrapper<>();
                staffOrganizationQueryWrapper.in("account_id", accountIds);
                List<StaffOrganization> staffOrganizations = staffOrganizationService.list(staffOrganizationQueryWrapper);

                //查询组织的负责人
                QueryWrapper<OrganizationManager> organizationManagerQueryWrapper = new QueryWrapper<>();
                organizationManagerQueryWrapper.in("account_id",accountIds);
                List<OrganizationManager> managers = organizationManagerService.list(organizationManagerQueryWrapper);
                Map<Integer, List<Integer>> accountOrgsMap = staffOrganizations.stream().collect(Collectors.groupingBy(StaffOrganization::getAccountId, Collectors.mapping(StaffOrganization::getOrgId, Collectors.toList())));
                Map<Integer,Integer> managerMap = managers.stream().collect(Collectors.toMap(OrganizationManager::getAccountId,OrganizationManager::getOrgId));
                if (staffOrganizations.isEmpty()) {
                    log.warn("账号未关联组织信息");
                    return;
                }
                List<Integer> orgIds = staffOrganizations.stream().map(i -> i.getOrgId()).distinct().collect(Collectors.toList());
                OrganizationQuery organizationQuery = new OrganizationQuery();
                organizationQuery.setIds(orgIds);
                Map<Integer, String> integerStringMap = organizationService.batchFullName(organizationQuery);

                for (OrgStaffTreeDTO orgStaffTreeDTO : orgStaffTreeDTOS) {
                    List<Integer> organizations = accountOrgsMap.get(orgStaffTreeDTO.getRelationId());
                    if (CollectionUtils.isNotEmpty(organizations)) {
                        orgStaffTreeDTO.setOrgNames(organizations.stream().map(i -> integerStringMap.get(i)).collect(Collectors.toList()));
                    }
                    if (null != managerMap.get(orgStaffTreeDTO.getRelationId()) && organization.getLevel() != 1){
                        //是否是当前组织的负责人+当前组织是否是根节点
                        if (managerMap.get(orgStaffTreeDTO.getRelationId()).equals(organization.getId())){
                            orgStaffTreeDTO.setIsManager(true);
                        }
                    }
                }
            }
        }
    }

    public List<OrganizationConfigDTO> tree(List<OrganizationConfig> organizationConfigs) {
        if (organizationConfigs.isEmpty()) {
            return Collections.emptyList();
        }
        List<OrganizationConfig> sort = organizationConfigs.stream().distinct().sorted(Comparator.comparing(OrganizationConfig::getLevel)).collect(Collectors.toList());
        // get top element
        OrganizationConfig organizationConfig = sort.get(0);
        List<OrganizationConfig> tops = sort.stream().filter(s -> organizationConfig.getLevel() == s.getLevel()).collect(Collectors.toList());

        // 封装根节点数据
        List<OrganizationConfigDTO> organizationConfigDTOS = tops.stream().map(o -> {
            OrganizationConfigDTO organizationConfigDTO = new OrganizationConfigDTO();
            BeanUtils.copyProperties(o, organizationConfigDTO);
            organizationConfigDTO.setIndustry(o.getIndustryId());
            return organizationConfigDTO;
        }).collect(Collectors.toList());

        // 过滤掉根节点，剩余子节点
        List<OrganizationConfig> nodes = organizationConfigs.stream()
                .filter(o -> !tops.stream().map(OrganizationConfig::getId).collect(Collectors.toList()).contains(o.getId()))
                .collect(Collectors.toList());

        organizationConfigDTOS.stream().forEach(o -> o.setChildren(this.listChildren(nodes, o.getId())));
        return organizationConfigDTOS;
    }


    private List<OrganizationConfigDTO> listChildren(List<OrganizationConfig> organizations, Integer parentId) {

        if (null == organizations || organizations.isEmpty()) {
            return Collections.emptyList();
        }
        // 过滤出子节点
        List<OrganizationConfig> organizationList = organizations.stream()
                .filter(organization -> organization.getParentId().equals(parentId)).distinct()
                .collect(Collectors.toList());
        // 移除处理节点
        organizations.removeAll(organizationList);
        // 封装子节点
        return organizationList.stream().map(organization -> {
            OrganizationConfigDTO organizationConfigDTO = new OrganizationConfigDTO();
            BeanUtils.copyProperties(organization, organizationConfigDTO);
            organizationConfigDTO.setChildren(this.listChildren(organizations, organizationConfigDTO.getId()));
            return organizationConfigDTO;
        }).collect(Collectors.toList());
    }


    @Data
    class OrganizationViewDTO {

        private Integer id;

        private String name;

        private String code;

        private OrganizationTypeEnum type;

        private Integer enterpriseId;

        private Integer organizationId;
    }

    /**
     * 组织类型
     *
     * @return
     */
    @GetMapping("/org/type/v2")
    public ResultJson orgType(@RequestHeader Integer industryId,
                              @RequestParam("enterpriseId") Integer enterpriseId) {
        OrganizationConfigQuery query = new OrganizationConfigQuery();
        query.setEnterpriseId(enterpriseId);
        query.setIndustryId(industryId);
        List<OrganizationConfig> organizationConfigs = organizationConfigFeignService.list(query);
        if (0 == organizationConfigs.size()) {
            query.setEnterpriseId(null);
            organizationConfigs = organizationConfigFeignService.list(query);
        }
        List<JSONObject> orgTypes = organizationConfigs.stream()
                .map(x -> {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("id", x.getType());
                    jsonObject.put("name", x.getName());
                    return jsonObject;
                }).distinct().collect(Collectors.toList());
        return ResultJson.success(orgTypes);
    }


    @PostMapping("/org/check-unique-code")
    public ResultJson checkUniqueCode(@RequestBody OrganizationDTO dto) {
        if (null == dto.getCode() || null == dto.getProjectId() || null == dto.getType()) {
            return ResultJson.fail("参数错误");
        }
        return organizationService.checkUniqueCode(dto);
    }

    /**
     * 获取随机编码
     *
     * @return
     */
    @GetMapping("/org/get-current-code")
    public ResultJson getCurrentCode() {
        return ResultJson.success().setResult(UUID.randomUUID().toString().replace("-", ""));
    }

    /**
     * 获取企业下组织唯一编码
     */
    @GetMapping("/org/get-unique-code")
    public ResultJson getUniqueCode( @RequestParam("enterpriseId") Integer enterpriseId){
        CodeGenerator codeGenerator = new CodeGenerator();
        String uniqueCode = codeGenerator.generateUniqueCode(enterpriseId,organizationService);
        return ResultJson.success(uniqueCode);
    }

    /**
     * 批量导入组织
     */
    @PostMapping("/org/import")
    public ResultJson importOrgs(@RequestHeader("industryId") Short industryId,
                                 @RequestParam MultipartFile file,
                                 Account account,
                                 @RequestParam Integer enterpriseId){
        account.setIndustryId(industryId);
        organizationService.createByImport(file,industryId,enterpriseId,account);
        return ResultJson.success("正在导入。。。");
    }

    /**
     * 导出组织
     */
    @GetMapping("/org/export")
    public void exportOrgs(@RequestParam(required = false) String keywords, @RequestParam Integer enterpriseId, HttpServletResponse response){
        organizationService.exportBatchOrg(keywords,enterpriseId,response);
    }

    /**
     * 下载组织导入模板
     */
    @RequestMapping("/org/export-template")
    public void exportTemplate(Integer enterpriseId,HttpServletResponse response) throws IOException {
        organizationService.exportOrganizationTemp(enterpriseId,response);
    }

    /**
     * 下载导入错误数据
     */
    @RequestMapping("/org/export-error")
    public void export(HttpServletResponse response,@RequestParam String fileId){
        organizationService.exportErrorByFileId(response,fileId);
    }

    @RequestMapping(value = "/org/import-history")
    public ResultJson importHistory(@RequestParam(value = "enterpriseId", required = false) Integer enterpriseId,
                                    @RequestParam(value = "fileName", required = false) String fileName,
                                    Page page){
        return organizationImportService.getOrganizationHistoryImport(enterpriseId,fileName,page);
    }
    /**
     * 整棵树（工作流用）
     * @param orgStaffListQueryDTO
     * @return
     */
    @RequestMapping(value = "/org/staff/all-tree")
    public ResultJson allTree(@RequestBody OrgStaffListQueryDTO orgStaffListQueryDTO){
        if (null == orgStaffListQueryDTO.getEnterpriseId()) {
            return ResultJson.fail("缺少企业信息");
        }
        OrgStaffTreeQueryDTO orgStaffTreeQueryDTO = new OrgStaffTreeQueryDTO();
        Integer pId = 0;
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(orgStaffListQueryDTO.getParentId())) {
            try {
                String[] s1 = orgStaffListQueryDTO.getParentId().split("_");
                String s = s1[1];
                if (!s1[0].equals("o")) {
                    return ResultJson.success(Collections.emptyList());
                }
                pId = Integer.valueOf(s);
                orgStaffTreeQueryDTO.setParentId(pId);
            } catch (Exception e) {
                e.printStackTrace();
                return ResultJson.success(Collections.emptyList());
            }
        }
        orgStaffTreeQueryDTO.setEnterpriseId(orgStaffListQueryDTO.getEnterpriseId());
        if (null!=orgStaffListQueryDTO.getKeywords()){
            orgStaffTreeQueryDTO.setKeywords(orgStaffListQueryDTO.getKeywords());
        }
        return organizationService.allToTree(orgStaffTreeQueryDTO);
    }

    /**
     * 获得所有组织数据
     */
    @RequestMapping(value = "/org/ent/allOrgs")
    public ResultJson allOrgs(){
        List<OrganizationDTO> list=organizationService.getOrgByEntId();
        return ResultJson.success(list);
    }

    /**
     * 获得所有路址空间
     */
    @RequestMapping(value = "/org/ent/allSpace")
    public ResultJson allSpace(){
        List<OrganizationDTO> list=organizationService.allSpace();
        return ResultJson.success(list);
    }

    /**
     * 获取最大序号
     */
    @GetMapping(value = "/org/get-max-sort")
    public ResultJson getMaxSort(@RequestParam(value = "type",required = false) Integer type,@RequestParam(value = "parentId") Integer parentId){
        List<Organization> organizationList = organizationService.list(new OrganizationQuery().withParentId(parentId).withTypes(Collections.singletonList(type)));
        organizationList = organizationList.stream().filter(i -> null != i.getSortField()).collect(Collectors.toList());
        int max = 0;
        if (CollectionUtils.isNotEmpty(organizationList)){
            max = organizationList.stream().mapToInt(Organization::getSortField).max().getAsInt();
        }
        return ResultJson.success("请求成功",max+1);
    }

    /**
     * 刷新排序
     * @param organizationQuery
     * @return
     */
    @RequestMapping(value = "/org/refresh-sort", method = RequestMethod.POST)
    public ResultJson refreshSort(@RequestBody OrganizationQuery organizationQuery) {
        if (null == organizationQuery.getTypeId() || null == organizationQuery.getParentId()){
            return ResultJson.fail("参数错误");
        }
        Integer parentId =  organizationQuery.getParentId();
        Integer typeId =  organizationQuery.getTypeId();
        //空间
        OrganizationTypeEnum organizationTypeEnum = OrganizationTypeEnum.valueOfId(organizationQuery.getTypeId());
        if (null == organizationTypeEnum || null == organizationTypeEnum.id){
            //自定义空间
            SpaceQuery spaceQuery = new SpaceQuery();
            spaceQuery.setParentId(parentId);
            spaceQuery.setTypeId(typeId);
            return spaceService.refreshSort(spaceQuery);
        }
        OrganizationQuery organizationQuery1 = new OrganizationQuery();
        switch (organizationTypeEnum) {
            case AREA:
                AreaQuery areaQuery = new AreaQuery();
                areaQuery.setParentId(parentId);
                return areaService.refreshSort(areaQuery);
            case ROOM:
                RoomQuery roomQuery = new RoomQuery();
                roomQuery.setParentId(parentId);
                return roomService.refreshSort(roomQuery);
            case BLOCK:
                BlockQuery blockQuery = new BlockQuery();
                blockQuery.setParentId(parentId);
                return blockService.refreshSort(blockQuery);
            case FLOOR:
                FloorQuery floorQuery = new FloorQuery();
                floorQuery.setParentId(parentId);
                return floorService.refreshSort(floorQuery);
            case BUILDING:
                BuildingQuery buildingQuery = new BuildingQuery();
                buildingQuery.setParentId(parentId);
                return buildingService.refreshSort(buildingQuery);
            case PUBLIC_AREA:
                PublicAreaQuery publicAreaQuery = new PublicAreaQuery();
                publicAreaQuery.setParentId(parentId);
                return publicAreaService.refreshSort(publicAreaQuery);
            case BALCONY:
                organizationQuery1.setParentId(parentId);
                organizationQuery1.setTypes(Collections.singletonList(Integer.valueOf(organizationTypeEnum.id)));
                return organizationService.refreshSort(organizationQuery1);
            case UNIT:
                organizationQuery1.setParentId(parentId);
                organizationQuery1.setTypes(Collections.singletonList(Integer.valueOf(organizationTypeEnum.id)));
                return organizationService.refreshSort(organizationQuery1);
            default:
                //自定义空间
                SpaceQuery spaceQuery = new SpaceQuery();
                spaceQuery.setParentId(parentId);
                spaceQuery.setTypeId(typeId);
                return spaceService.refreshSort(spaceQuery);
        }
    }
}

